package com.report.reportserver.config.security;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.report.reportserver.model.User;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @ ClassName: JwtTokenUtils
 * @ Description：JwtTokenUtil的工具类
 * @ Modified By：
 * @ Version:
 * @ Author     ：LiYing
 * @ Date       ：Created in 22:00 2022/3/7
 */
@Component
public class JwtTokenUtils {

    /**
     * SALT：盐，或称密钥。加密使用，需要服务端保管好
     */
    private static final String SALT = "029ef05131b5501f319ae490354df5c9a23be01e3c1d40c79d5d52fe992dbe";

    /**
     * Token 有效时长
     */
    private static final long EXPIRE_DATE = 60 * 60 * 1000;

    /**
     * 生成 Token 字符串 必须 setAudience 接收者 setExpiration 过期时间
     */
    public static String createToken(User user) {
        try {
            // token过期时间
            Date expirationDate = new Date(System.currentTimeMillis() + EXPIRE_DATE);
            //设置头部信息,类型以及签名所用的算法
            Map<String, Object> header = new HashMap<>();
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            // 生成 Token
            String token = JWT.create()
                    .withHeader(header)
                    // 设置 Token 签发者 可选
                    .withIssuer("SpringBoot")
                    // 根据用户名设置 Token 的接受者
                    .withAudience(user.getUserName())
                    // 设置过期时间
                    .withExpiresAt(expirationDate)
                    // 设置 Token 生成时间 可选
                    .withIssuedAt(new Date())
                    // 通过 claim 方法设置一个 key = role，value = userRole 的值
                    .withClaim("userId", String.valueOf(user.getId()))
                    .withClaim("username", user.getUserName())
                    .withClaim("password", user.getUserPassword())
                    // 设置加密密钥和加密算法，注意要用私钥加密且保证私钥不泄露
                    .sign(Algorithm.HMAC256(SALT));
            return token;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 验证 Token ，并获取到用户名和用户权限信息
     */
    public static User validationToken(String token) {
        try {
            if (token != null) {
                // 解密也需要该 salt，所以它很重要，不要泄露
                JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SALT)).build();
                DecodedJWT jwt = verifier.verify(token);

                User user = new User();
                //System.out.println(jwt.getClaim("username").asString()+"---- is coming");
                // 取出里面的用户名
                user.setUserName(jwt.getClaim("username").asString());
                // 取出里面的用户id
                user.setId(Integer.parseInt(jwt.getClaim("userId").asString()));
                return user;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
